// 手动节流阀
interface eventHandler {
  (e: Event): any
}
interface $throttle_parm {
  el: null | HTMLDivElement
  handler: eventHandler | any
  event: string | null
  model?: 0 | 1
  threshold?: number
}
// 包装方法
function addThrottle ({el = null, event = null, handler = null, threshold = 250, model = 0}: $throttle_parm) {
  let settimeId: number | any
  let settimeId2: number | any
  let start = Date.now();
  (<HTMLElement>el).addEventListener(<string>event, <eventHandler>(model == 0 ? cddThrottle0 : cddThrottle1))

  // 间隔模式
  function cddThrottle0 (e: Event) {
    clearTimeout(settimeId)
    settimeId = setTimeout(() => {
      handler(e)
      clearTimeout(settimeId)
    }, threshold);
  }

  // 频率模式
  function cddThrottle1 (e: Event) {
    clearTimeout(settimeId2)
    let end = Date.now()
    if (end - start >= threshold) {
      clearTimeout(settimeId2)
      handler(e)
      start = end
    }
    settimeId2 = setTimeout(() => {
      handler(e)
    }, threshold > 150 ? 100 : threshold);
  }
}

// 节流阀函数
export default class Throttle {
  wait = 150
  times = 10
  type = 1//1基于时间，2基于次数

  constructor (option?: {wait?: number, times?: number, type?: number}) {
    if (option) {
      this.wait = option.wait || this.wait
      this.times = option.times || this.times
      this.type = option.type || this.type
    }
  }

  static makeFun (fun: Function, option?: {type?: number, wait?: number, times?: number, before?: Function, after?: Function}) {
    const c = new Throttle(option)
    // 时间方式
    if (c.type === 1) {
      return c.byDuration(fun)
    }
    // 次数方式
    return c.byTimes(fun)
  }

  // 时间的节流阀
  byDuration (fun: Function, option?: {wait?: number, before?: Function, after?: Function}) {
    if (option) {
      this.wait = option.wait || this.wait
      option.before && (option.before())
    }
    // 如果有befor则进行处理
    let tId: any = 0
    let tcount = Date.now();
    return (params: anyObj) => {
      if (Date.now() - tcount >= this.wait) {
        tcount = Date.now()
        // setTimeout(() => {
        fun(params)
        // }, 0);
      }
      // 停止则进行的处理
      clearTimeout(tId)
      tId = setTimeout(() => {
        if (option) {
          option.after && (option.after())
        }
        fun(params)
      }, Math.max(500, this.wait));
    }
  }

  // 次数节流阀
  byTimes (fun: Function, option?: {times?: number, before?: Function, after?: Function}) {
    if (option) {
      this.times = option.times || this.times
      option.before && (option.before())
    }
    let _times = 0
    let tId: any = 0
    return (params: any) => {
      _times++
      if (_times >= this.times) {
        _times = 0
        // setTimeout(() => {
        fun(params)
        // }, 0);
      }
      // 停止则进行的处理
      clearTimeout(tId)
      tId = setTimeout(() => {
        if (option) {
          option.after && (option.after())
        }
        // 最后执行一下
        fun(params)
      }, 300);
    }
  }

}

export {addThrottle, Throttle}
